package com.sync.utils;

import java.nio.ByteBuffer;

/**
 * 大部分用户的操作系统（如windows, FreeBsd,Linux）是Little Endian的。 少部分，如MAC OS ,是Big Endian
 * 的。
 * 
 * 字节转换，当前值支持Little Endian
 * 
 * @author Mark Hsiu
 *
 */
public class Bits {

	private Bits() {
	}

	public static void put(byte[] data, int offset, byte val) {
		data[offset] = val;
	}

	// -- get/put char --

	static private char makeChar(byte b1, byte b0) {
		return (char) ((b1 << 8) | (b0 & 0xff));
	}

	public static char toChar(byte b0, byte b1) {
		return makeChar(b0, b1);
	}

	private static byte char1(char x) {
		return (byte) (x >> 8);
	}

	private static byte char0(char x) {
		return (byte) (x);
	}

	public static void putChar(byte[] data, int offset, char val) {
		data[offset] = char1(val);
		data[offset + 1] = char0(val);
	}

	// -- get/put short --

	static private short makeShort(byte b1, byte b0) {
		return (short) ((b1 << 8) | (b0 & 0xff));
	}

	public static short toShort(byte b0, byte b1) {
		return makeShort(b0, b1);
	}

	private static byte short1(short x) {
		return (byte) (x >> 8);
	}

	private static byte short0(short x) {
		return (byte) (x);
	}

	public static void putShort(byte[] data, int offset, short val) {
		data[offset] = short1(val);
		data[offset + 1] = short0(val);
	}

	// -- get/put int --

	public static void putInt(byte[] data, int offset, int val) {
		data[offset] = int3(val);
		data[offset + 1] = int2(val);
		data[offset + 2] = int1(val);
		data[offset + 3] = int0(val);
	}

	static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
		return (((b3) << 24) | ((b2 & 0xff) << 16) | ((b1 & 0xff) << 8) | ((b0 & 0xff)));
	}

	public static int toInt(byte b0, byte b1, byte b2, byte b3) {
		return makeInt(b0, b1, b2, b3);
	}

	public static int byteToInt(byte[] data, int offset) {
		return Bits.toInt(data[offset + 0], data[offset + 1], data[offset + 2], data[offset + 3]);
	}

	private static byte int3(int x) {
		return (byte) (x >> 24);
	}

	private static byte int2(int x) {
		return (byte) (x >> 16);
	}

	private static byte int1(int x) {
		return (byte) (x >> 8);
	}

	private static byte int0(int x) {
		return (byte) (x);
	}

	// -- get/put long --

	static private long makeLong(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0) {
		return ((((long) b7) << 56) | (((long) b6 & 0xff) << 48) | (((long) b5 & 0xff) << 40)
				| (((long) b4 & 0xff) << 32) | (((long) b3 & 0xff) << 24) | (((long) b2 & 0xff) << 16)
				| (((long) b1 & 0xff) << 8) | (((long) b0 & 0xff)));
	}

	public static long toLong(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
		return makeLong(b0, b1, b2, b3, b4, b5, b6, b7);
	}

	// -- get/put float --

	// -- get/put Double --

	public static double toDouble(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
		return Double.longBitsToDouble(makeLong(b0, b1, b2, b3, b4, b5, b6, b7));
	}

	/**
	 * long to int + int
	 */
	public static void longToIntInt(long longVal, int[] vals) {
		vals[0] = (int) longVal;
		vals[1] = (int) (longVal >> 32);
	}

	/**
	 * int + int to long
	 */
	public static long intIntToLong(int firstVal, int secondVal) {
		long val = secondVal << 32;
		val = val << 32;
		val = val | firstVal;
		return val;
	}

  
	public static void IntToByte(int i ,ByteBuffer byteBuffer) {
		  
	        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); 
	        char[] buf = new char[size];
	        getChars(i, size, buf);
	        for(int indx=0;indx<size;indx++){
	        	byteBuffer.put((byte) buf[indx]);
	        }
	}

	final static char[] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1',
			'1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3',
			'3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5',
			'5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7',
			'7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', };

	final static char[] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7',
			'8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8',
			'9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', };

	final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
			'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };

	static void getChars(int i, int index, char[] buf) {
		int q, r;
		int charPos = index;
		char sign = 0;

		if (i < 0) {
			sign = '-';
			i = -i;
		}

		// Generate two digits per iteration
		while (i >= 65536) {
			q = i / 100;
			// really: r = i - (q * 100);
			r = i - ((q << 6) + (q << 5) + (q << 2));
			i = q;
			buf[--charPos] = DigitOnes[r];
			buf[--charPos] = DigitTens[r];
		}

		// Fall thru to fast mode for smaller numbers
		// assert(i <= 65536, i);
		for (;;) {
			q = (i * 52429) >>> (16 + 3);
			r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
			buf[--charPos] = digits[r];
			i = q;
			if (i == 0)
				break;
		}
		if (sign != 0) {
			buf[--charPos] = sign;
		}
	}

	final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE };

	// Requires positive x
	static int stringSize(int x) {
		for (int i = 0;; i++)
			if (x <= sizeTable[i])
				return i + 1;
	}

	public static void main(String[] args) {
		int a = 121;
		int b = 23232;
		long l = intIntToLong(a, b);
		int[] vals = new int[2];
		longToIntInt(l, vals);
		System.out.println(vals[0]);
		System.out.println(vals[1]);
	}

}
